package com.compass.service;

import com.compass.constant.Admin;
import com.compass.entity.BaseProtocolDo;
import com.compass.entity.DubboDo;
import com.compass.entity.HttpDo;
import com.compass.mapper.BaseProtocolMapper;
import com.compass.mapper.DubboProtocolMapper;
import com.compass.mapper.HttpProtocolMapper;
import com.compass.util.SessionUtil;
import com.compass.vo.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ReflectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: li
 * Date: 2019/3/31
 * Time: 11:35
 * PROJECT：compass
 * PACKAGE: com.compass
 *
 * @author:55324936@qq.com To change this template use File | Settings | File Templates.
 */
@Service
@Slf4j
public class ComponentService {

    @Autowired
    DubboProtocolMapper dubboProtocolMapper;
    @Autowired
    HttpProtocolMapper httpProtocolMapper;

    /**
     * 获取组件列表
     **/
    public TablePage componentList(HttpServletRequest httpServletRequest) {
        Map map = this.getMapperAndTarget(httpServletRequest);
        BaseProtocolDo baseProtocolDo = (BaseProtocolDo) map.get("baseProtocolDo");
        BaseProtocolMapper baseProtocolMapper = (BaseProtocolMapper) map.get("baseProtocolMapper");
        Integer projectId = SessionUtil.getSessionUser().getLastProjectId();
        baseProtocolDo.setProjectId(projectId);
        Page page = PageHelper.startPage(baseProtocolDo.getPageNum(), baseProtocolDo.getPageSize(), true);

        List<BaseProtocolDo> baseProtocolDoList = baseProtocolMapper.componentList(baseProtocolDo);
        long total = page.getTotal();
        TablePage tablePage = new TablePage();
        tablePage.setTotal(total);
        tablePage.setRows(baseProtocolDoList);
        // interfaceType,userName
        //非必须 interfaceAliasName
        return tablePage;
    }

    /**
     * 通过id获取组件信息
     *
     * @param httpServletRequest
     **/
    public BaseProtocolDo getComponentById(HttpServletRequest httpServletRequest) {
        Map map = this.getMapperAndTarget(httpServletRequest);
        BaseProtocolMapper baseProtocolMapper = (BaseProtocolMapper) map.get("baseProtocolMapper");
        BaseProtocolDo baseProtocolDo = (BaseProtocolDo) map.get("baseProtocolDo");
        Integer id = baseProtocolDo.getId();
        BaseProtocolDo baseProtocolDo1 = null;
        if (null != id && id.intValue() > 0) {
            baseProtocolDo1 = baseProtocolMapper.getComponentById(id);
            return baseProtocolDo1;
        }
        return baseProtocolDo1;
    }

    /**
     * 新增、修改组件
     *
     * @param httpServletRequest
     **/
    public ResponseMessage saveComponent(HttpServletRequest httpServletRequest) {
        Map map = this.getMapperAndTarget(httpServletRequest);
        BaseProtocolDo baseProtocolDo = (BaseProtocolDo) map.get("baseProtocolDo");
        LoginUser loginUser = SessionUtil.getSessionUser();
        baseProtocolDo.setProjectId(loginUser.getLastProjectId());
        baseProtocolDo.setUserName(loginUser.getUserName());
        BaseProtocolMapper baseProtocolMapper = (BaseProtocolMapper) map.get("baseProtocolMapper");
        Integer id = baseProtocolDo.getId();
        if (null != id) {
            baseProtocolMapper.modifyComponent(baseProtocolDo);
        } else {
            baseProtocolMapper.addComponent(baseProtocolDo);
        }
        return ResponseMessage.successResponse();
    }
    /**
     * 删除组件
     *
     * **/
    @Transactional
    public ResponseMessage deleteComponent(HttpServletRequest httpServletRequest) {
        Map map = this.getMapperAndTarget(httpServletRequest);
        BaseProtocolDo baseProtocolDo = (BaseProtocolDo) map.get("baseProtocolDo");
        BaseProtocolMapper baseProtocolMapper = (BaseProtocolMapper) map.get("baseProtocolMapper");
        try {
            baseProtocolMapper.deleteComponent(baseProtocolDo.getId());
        } catch (Exception e) {
            log.error("删除组件异常", e);
            return ResponseMessage.errorResponse("删除组件异常," + Admin.ADMIN_MESSAGE);
        }
        //那么组件下面的用例是不是也被删除了,现在先不写
        return ResponseMessage.successResponse();
    }


    // dubbo 和 http 是不是操作不同的table 也是不同mapper

    /**
     * 获取mapper和入参对象
     *
     * @param httpServletRequest
     **/
    private Map getMapperAndTarget(HttpServletRequest httpServletRequest) {
        String interfaceType = httpServletRequest.getParameter("interfaceType");
        Map map = new HashMap();
        BaseProtocolDo baseProtocolDo = null;
        BaseProtocolMapper baseProtocolMapper = null;
        if (interfaceType.equalsIgnoreCase("dubbo")) {
            DubboDo dubboDo = new DubboDo();
            Field[] fields = FieldUtils.getAllFields(dubboDo.getClass()); //获取class的所有属性，包括父类的
            this.copyFiled(fields, dubboDo, httpServletRequest);
            baseProtocolDo = dubboDo;
            baseProtocolMapper = dubboProtocolMapper;
        } else if (interfaceType.equalsIgnoreCase("http")) {
            HttpDo httpDo = new HttpDo();
            Field[] fields = FieldUtils.getAllFields(httpDo.getClass()); //获取class的所有属性，包括父类的
            this.copyFiled(fields, httpDo, httpServletRequest);
            baseProtocolDo = httpDo;
            baseProtocolMapper = httpProtocolMapper;
        }
        map.put("baseProtocolDo", baseProtocolDo);
        map.put("baseProtocolMapper", baseProtocolMapper);
        return map;
    }


    /**
     * 复制httpRequest的属性到目标实例
     *
     * @param fields
     * @param target
     * @param httpServletRequest
     **/
    private void copyFiled(Field[] fields, Object target, HttpServletRequest httpServletRequest) {
        for (Field field : fields) {
            field.setAccessible(true); //把私有属性设置 public
            String name = field.getName(); //获取属性名 例如：zkAddress
            String value = httpServletRequest.getParameter(name);
            if (StringUtils.isEmpty(value)) {
                continue;
            }
            String typeName = field.getGenericType().getTypeName(); //java.lang.String java.lang.Integer
            if (typeName.equalsIgnoreCase("java.lang.String")) {
                ReflectionUtils.setField(field, target, value); //1.你要设置的属性，2.目标类，3.具体的值
            } else if (typeName.equalsIgnoreCase("java.lang.Integer")) {
                Integer i = Integer.parseInt(value);
                ReflectionUtils.setField(field, target, i);
            }
        }
    }
}
